# encoding: utf-8
# 项目名称： 常用设计模式
# @File  : 010-组合模式.py
# @Author: sun hao
# @Desc : 
# @Date  :   20:33 2024/10/29
from abc import ABCMeta, abstractmethod


class Graphic(metaclass=ABCMeta):
    @abstractmethod
    def draw(self):
        pass


class Point(Graphic):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        return f'(点:{self.x}, {self.y})'

    def draw(self):
        print(str(self))


class Line(Graphic):
    def __init__(self, p1, p2):
        self.p1 = p1
        self.p2 = p2

    def __str__(self):
        return f'(线段:{self.p1}, {self.p2})'

    def draw(self):
        print(str(self))


class Picture(Graphic):
    def __init__(self, iterable):
        self.children = []
        for g in iterable:
            self.add(g)

    def add(self, graphic):
        self.children.append(graphic)

    def draw(self):
        print('----复合图形 S----')
        for g in self.children:
            g.draw()
        print('----复合图形 E----')


p1 = Point(2, 3)
l1 = Line(Point(3, 4), Point(4, 5))
l2 = Line(Point(1, 5), Point(2, 8))
pic1 = Picture([p1, l1, l2])
pic1.draw()


# 示例2：用户界面组件

class UIComponent(metaclass=ABCMeta):
    @abstractmethod
    def render(self):
        pass


class Button(UIComponent):
    def __init__(self, label):
        self.label = label

    def render(self):
        print(f"渲染按钮: {self.label}")


class Panel(UIComponent):
    def __init__(self, title):
        self.title = title
        self.children = []

    def add(self, component):
        self.children.append(component)

    def render(self):
        print(f"渲染面板: {self.title}")
        for child in self.children:
            child.render()


# 创建UI组件
button1 = Button("按钮1")
button2 = Button("按钮2")

# 创建面板并添加组件
panel1 = Panel("面板1")
panel1.add(button1)
panel1.add(button2)

# 渲染面板
panel1.render()


# 示例3：文件系统浏览器

class FileSystemItem(metaclass=ABCMeta):
    @abstractmethod
    def display(self):
        pass


class File(FileSystemItem):
    def __init__(self, name):
        self.name = name

    def display(self):
        print(f"显示文件: {self.name}")


class Directory(FileSystemItem):
    def __init__(self, name):
        self.name = name
        self.children = []

    def add(self, item):
        self.children.append(item)

    def display(self):
        print(f"显示目录: {self.name}")
        for child in self.children:
            child.display()


# 创建文件和目录
file1 = File("文件1.txt")
file2 = File("文件2.txt")
dir1 = Directory("子目录1")
dir1.add(file1)
dir1.add(file2)

# 创建根目录
root_dir = Directory("根目录")
root_dir.add(dir1)

# 显示文件系统结构
root_dir.display()
